#pragma once

#include <iostream>
#include <map>
#include <vector>

#include "ClassField.h"
#include "ClassMethod.h"
#include "ClassObject.h"
#include "Singleton/singleton.h"
using namespace bin;

// 通过类型别名，当别名获取地址时，便可以像构造函数那样获取类指针，从而进一步调用成员
typedef ClassObject* (*FactoryClass)(void);

class ClassFactory
{
  private:
    std::map<std::string, FactoryClass>              ClassMap;
    std::map<std::string, std::vector<ClassField*>>  ClassFieldMap;
    std::map<std::string, std::vector<ClassMethod*>> ClassMethodMap;

    friend class Singleton<ClassFactory>;

  private:
    ClassFactory() {}
    ~ClassFactory() {}

  public: // 类
    void registerClass(const std::string& classname, FactoryClass classobject);
    ClassObject* getClass(const std::string& classname);
    int  getClassCount();

  public: // 类域成员
    void        registerClassField(const std::string& classname,
                                   const std::string& name,
                                   const std::string& type,
                                   size_t             offset);
    ClassField* getClassField(const std::string& classname,
                              const std::string& fieldname);
    ClassField* getClassField(const std::string& classname, int pos);
    int         getClassFieldCount(const std::string& classname);

  public: // 类方法
    void         registerClassMethod(const std::string& classname,
                                     const std::string& methodname,
                                     uintptr_t          method);
    ClassMethod* getClassMethod(const std::string& classname,
                                const std::string& methodname);
    ClassMethod* getClassMethod(const std::string& classname, int pos);
};
